﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.SharePoint;
using Linxiao.SP.Tools.GroupUsersMover.Library;

namespace Linxiao.SP.Tools.GroupUsersMover
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private GUMSite leftSite;
        private GUMSite rightSite;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void btMoveToLeft_Click(object sender, RoutedEventArgs e)
        {
            MoveGroup(rightSite, leftSite, tvSite2, tvSite1);
        }

        private void btMoveToRight_Click(object sender, RoutedEventArgs e)
        {
            MoveGroup(leftSite, rightSite, tvSite1, tvSite2);
        }

        private void btSite1Load_Click(object sender, RoutedEventArgs e)
        {
            string siteUrl = this.tbSite1Url.Text;

            try
            {
                //load site and get user groups
                leftSite = new GUMSite(siteUrl);
                UpdateTreeview(leftSite, tvSite1);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void btSite2Load_Click(object sender, RoutedEventArgs e)
        {
            string siteUrl = this.tbSite2Url.Text;

            try
            {
                //load site and get user groups
                rightSite = new GUMSite(siteUrl);
                UpdateTreeview(rightSite, tvSite2);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void tvSite1_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            SelectByRightClick(e);
        }

        private void tvSite2_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            SelectByRightClick(e);
        }

        private void Site1DeleteMenuItem_Click(object sender, RoutedEventArgs e)
        {
            DeleteGroupOrUser(tvSite1, leftSite);
        }

        private void Site1RemoveAssociationMenuItem_Click(object sender, RoutedEventArgs e)
        {
            RemoveAssociation(tvSite1, leftSite);
        }

        private void Site2DeleteMenuItem_Click(object sender, RoutedEventArgs e)
        {
            DeleteGroupOrUser(tvSite2, rightSite);
        }

        private void Site2RemoveAssociationMenuItem_Click(object sender, RoutedEventArgs e)
        {
            RemoveAssociation(tvSite2, rightSite);
        }

        /// <summary>
        /// Move a group to destination site
        /// </summary>
        /// <param name="itemName"></param>
        /// <param name="sourceSite"></param>
        /// <param name="destinationSite"></param>
        private void MoveGroup(GUMSite sourceSite, GUMSite destinationSite, TreeView soruceTreeView, TreeView destinationTreeView)
        {
            try
            {
                if (sourceSite == null)
                    throw new Exception("Please load the soruce site.");

                if (destinationSite == null)
                    throw new Exception("Please load the destination site.");

                if (soruceTreeView.SelectedItem == null)
                    throw new Exception("No item is selected in the source site.");

                TreeViewNode selectedNode = soruceTreeView.SelectedItem as TreeViewNode;
                if (selectedNode.Type == TreeViewNodeType.Group)
                {
                    sourceSite.MoveGroup(selectedNode.Name, destinationSite);
                    UpdateTreeview(destinationSite, destinationTreeView);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        /// <summary>
        /// Delete the selected group or user
        /// </summary>
        /// <param name="treeview"></param>
        /// <param name="site"></param>
        public void DeleteGroupOrUser(TreeView treeview, GUMSite site)
        {
            if (treeview.SelectedItem != null)
            {
                try
                {
                    TreeViewNode selectedItem = treeview.SelectedItem as TreeViewNode;
                    //remove group association
                    if (selectedItem.Type == TreeViewNodeType.Group)
                        site.RemoveGroup(selectedItem.Name);
                    //remove users
                    else if (selectedItem.Type == TreeViewNodeType.User)
                    {
                        site.RemoveUser(selectedItem.LoginName, selectedItem.ParentGroup);
                    }

                    UpdateTreeview(leftSite, tvSite1);
                    UpdateTreeview(rightSite, tvSite2);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
            }           
        }

        /// <summary>
        /// Remove role assignment of the selected group from current site
        /// </summary>
        /// <param name="treeview"></param>
        /// <param name="site"></param>
        private void RemoveAssociation(TreeView treeview, GUMSite site)
        {
            if (treeview.SelectedItem != null)
            {
                try
                {
                    TreeViewNode selectedItem = treeview.SelectedItem as TreeViewNode;
                    //remove group association
                    if (selectedItem.Type == TreeViewNodeType.Group)
                        site.RemoveGroupRoleAssignment(selectedItem.Name);
                    //remove users
                    else if (selectedItem.Type == TreeViewNodeType.User)
                    {
                        site.RemoveUser(selectedItem.LoginName, selectedItem.ParentGroup);
                    }

                    UpdateTreeview(site, treeview);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
            }           
        }

        /// <summary>
        /// Populate Treeview with groups/users in the current site
        /// </summary>
        /// <param name="treeView"></param>
        /// <param name="principals"></param>
        /// <param name="spWeb"></param>
        private void populateTreeview(TreeView treeView, IList<SPPrincipal> principals, SPWeb spWeb)
        {
            System.IO.Stream rootImageStream = this.GetType().Assembly.GetManifestResourceStream("Linxiao.SP.Tools.GroupUsersMover.Images.refresh.png");

            var groupUri = new Uri(@"/Linxiao.SP.Tools.GroupUsersMover;component/Images/group.gif", UriKind.Relative);
            var userUri = new Uri(@"/Linxiao.SP.Tools.GroupUsersMover;component/Images/user.gif", UriKind.Relative);
            BitmapImage groupImage = new BitmapImage(groupUri);
            BitmapImage userImage = new BitmapImage(userUri);

            var node = new List<TreeViewNode>();

            foreach (SPPrincipal principal in principals)
            {
                if (principal is SPGroup)
                {
                    SPGroup group = principal as SPGroup;
                    TreeViewNode groupNode = new TreeViewNode();
                    groupNode.Name = group.Name;
                    groupNode.Type = TreeViewNodeType.Group;
                    groupNode.Icon = groupImage;
                    node.Add(groupNode);

                    //Populate users
                    foreach (SPUser user in group.Users)
                    {
                        TreeViewNode userNode = new TreeViewNode();
                        userNode.Name = user.Name;
                        userNode.LoginName = user.LoginName;
                        userNode.Type = TreeViewNodeType.User;
                        userNode.Icon = userImage;
                        userNode.ParentGroup = group.Name;
                        groupNode.Children.Add(userNode);
                    }
                }
                else
                {
                    SPUser user = principal as SPUser;
                    TreeViewNode userNode = new TreeViewNode();
                    userNode.Name = user.Name;
                    userNode.LoginName = user.LoginName;
                    userNode.Type = TreeViewNodeType.User;
                    userNode.Icon = userImage;
                    node.Add(userNode);
                }
                
            }

            treeView.ItemsSource = node;

        }

        /// <summary>
        /// Select a treeview item by right click
        /// </summary>
        /// <param name="e"></param>
        private void SelectByRightClick(MouseButtonEventArgs e)
        {
            DependencyObject source = e.OriginalSource as DependencyObject;
            while (source != null && !(source is TreeViewItem))
                source = VisualTreeHelper.GetParent(source);
            TreeViewItem item = source as TreeViewItem;

            if (item != null)
            {
                item.Focus();
                //e.Handled = true; 
            } 
        }

        /// <summary>
        /// Update treeview 
        /// </summary>
        /// <param name="site"></param>
        /// <param name="treeview"></param>
        private void UpdateTreeview(GUMSite site, TreeView treeview)
        {
            IList<SPPrincipal> principals = site.GetGroups();
            populateTreeview(treeview, principals, site.GetSite());
        }

    }
}
